package org.fsconnector.cci;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;

public class FSFile implements Serializable, Comparable<FSFile> {

	class FSFileFilter implements java.io.FilenameFilter {
		private FilenameFilter filter;

		public FSFileFilter(FilenameFilter filter) {
			this.filter = filter;
		}

		public boolean accept(File dir, String name) {
			return filter == null ? true : filter.accept(name);
		}
		
		public String toString() {
			return "" + filter;
		}
	}

	private static final long serialVersionUID = 6766653181640822304L;
	private final FSConnection connection;
//	private final File root;
	private final File file;
	private final String path;

	protected FSFile(FSConnection connection, File absoluteFile, String relativePath) {
//		System.err.println("FSFile(" + connection + ", " + absoluteFile + ", " + relativePath + ")");
		this.connection = connection;
//		this.root = root;
//		this.path = path;
//		this.file = new File(root, path);
		this.file = absoluteFile;
		this.path = relativePath;
	}

	public boolean canRead() {
		return file.canRead();
	}

	public boolean canWrite() {
		return file.canWrite();
	}

	public int compareTo(FSFile other) {
		return file.compareTo(other.file);
	}

	public void createNewFile() throws IOException {
		boolean success = file.createNewFile();
		if(!success) throw new IOException();
	}

	public void delete() throws DeleteException {
		boolean success = file.delete();
		if(!success) throw new DeleteException();
	}

	@Override
	public boolean equals(Object obj) {
		if(!(obj instanceof FSFile)) return false;
		return file.equals(((FSFile)obj).file);
	}

	public boolean exists() {
		return file.exists();
	}

	public String getName() {
		return file.getName();
	}

	public String getParent() {
		String path = getPath();
		if(path.equals("/")) return null;
		String parent = path.substring(0, path.lastIndexOf('/'));
		return parent.equals("") ? "/" : parent;
	}

	public FSFile getParentFile() {
		String parent = getParent();
		return parent == null ? null : connection.getFile(parent);
	}

	public String getPath() {
		return path;
	}

	@Override
	public int hashCode() {
		return file.hashCode();
	}

	public boolean isDirectory() {
		return file.isDirectory();
	}

	public boolean isFile() {
		return file.isFile();
	}

	public boolean isHidden() {
		return file.isHidden();
	}

	public long lastModified() {
		return file.lastModified();
	}

	public long length() {
		return file.length();
	}

	public String[] list() {
		return file.list();
	}

	public String[] list(FilenameFilter filter) {
		return file.list(new FSFileFilter(filter));
	}

	public FSFile[] listFiles() {
		return listFiles(null);
	}

	public FSFile[] listFiles(FilenameFilter filter) {
//		File[] files = manager.listFiles(new FSFileFilter(filter));
//		FSFile[] fsFiles = new FSFile[files.length];
//		for(int i = 0 ; i < files.length ; ++i) {
//			fsFiles[i] = new FSFile(files[i]);
//		}
//		return fsFiles;
		String[] files = list(filter);
		FSFile[] fsFiles = new FSFile[files.length];
		for(int i = 0 ; i < files.length ; ++i) {
			fsFiles[i] = connection.getFile(this, files[i]);
		}
		return fsFiles;
	}

	public void mkDir() throws CreateException {
		boolean success = file.mkdir();
		if(!success) throw new CreateException();
	}

	public void mkDirs() throws CreateException {
		boolean success = file.mkdirs();
		if(!success) throw new CreateException();
	}

	public void renameTo(FSFile dest) throws RenameException {
		boolean success = file.renameTo(dest.file);
		if(!success) throw new RenameException();
	}

	public void setLastModified(long milliseconds) throws SetException {
		boolean success = file.setLastModified(milliseconds);
		if(!success) throw new SetException();
	}

	public void setReadOnly() throws SetException {
		boolean success = file.setReadOnly();
		if(!success) throw new SetException();
	}

	@Override
	public String toString() {
		return getPath();
	}

	protected File getFile() {
		return file;
	}

}
